{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "SVD（Singular Value Decomposition）分解是一种矩阵分解的方法，它将一个矩阵分解为一个正交矩阵（U）和一个对角矩阵（D）的乘积，其中对角矩阵的元素是非负数。SVD分解在许多领域都有广泛的应用，例如图像处理、推荐系统等。\n",
    "\n",
    "以下是使用Python实现SVD分解算法的步骤：\n",
    "\n",
    "导入所需库："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "定义一个函数，用于计算矩阵的SVD分解："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def svd_decomposition(matrix):\n",
    "    u, s, vh = np.linalg.svd(matrix)\n",
    "    return u, s, vh.T\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "定义一个函数，用于计算矩阵的奇异值："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def calculate_singular_values(matrix):\n",
    "    u, s, vh = svd_decomposition(matrix)\n",
    "    return s\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "定义一个函数，用于计算矩阵的近似：\n",
    "\n",
    "这段Python代码的目的是对一个矩阵进行奇异值分解（SVD），并计算其近似值。具体来说，它实现了以下步骤：\n",
    "\n",
    "1. 导入所需的库：`numpy`。\n",
    "2. 定义一个名为`calculate_approximation`的函数，该函数接受两个参数：`matrix`（需要分解的矩阵）和`k`（需要保留的奇异值的数量）。\n",
    "3. 使用`svd_decomposition`函数对`matrix`进行奇异值分解，并将结果存储在`u`、`s`和`vh`中。\n",
    "4. 提取前`k`个奇异值和对应的右奇异矩阵`vh_k`。\n",
    "5. 计算近似值`u_k @ s_k @ vh_k`，并将其返回。\n",
    "\n",
    "这个函数可以用于计算矩阵的低秩近似，这在处理大型矩阵时非常有用，因为它可以减少计算复杂度和存储需求。在某些应用中，例如图像压缩和推荐系统，这个函数可以用于减少数据的大小和计算成本。\n",
    "\n",
    "需要注意的是，这个函数假设`matrix`是一个二维矩阵。如果`matrix`是一个一维数组，那么需要先将其转换为二维矩阵，然后再应用此函数。此外，`k`的值应该大于等于`matrix`的秩，否则可能会导致错误的结果。\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def calculate_approximation(matrix, k):\n",
    "    u, s, vh = svd_decomposition(matrix)\n",
    "    u_k = u[:, :k]\n",
    "    s_k = np.diag(s[:k])\n",
    "    vh_k = vh[:k, :]\n",
    "    return u_k @ s_k @ vh_k\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "测试SVD分解算法："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "U:\n",
      "[[-0.26021189 -0.03104021  0.12313554  0.51701378  0.14007664  0.25125735\n",
      "   0.32485187  0.3760589  -0.56220036 -0.0555938 ]\n",
      " [-0.26295004 -0.2523338   0.31480281  0.38063751 -0.0454435  -0.2951104\n",
      "   0.26096997 -0.37984487  0.25819765  0.50496581]\n",
      " [-0.31420324 -0.36075441 -0.23388895  0.10133516  0.36556756  0.34104053\n",
      "  -0.24471754  0.33646081  0.5277981   0.0674393 ]\n",
      " [-0.34642719  0.16609698  0.42478928 -0.11023776  0.08388411 -0.55732534\n",
      "  -0.03713174  0.39748921  0.19662223 -0.37962728]\n",
      " [-0.28496309  0.57094455 -0.00405449 -0.15530482  0.52523481  0.23602661\n",
      "   0.28485694 -0.3765402   0.1101968  -0.04508693]\n",
      " [-0.38583945 -0.16199027 -0.40374704  0.15838272  0.15163629 -0.33604817\n",
      "  -0.40923393 -0.39518677 -0.34454099 -0.24189851]\n",
      " [-0.33120484 -0.1337468   0.29180339 -0.57777403  0.0500817   0.12227398\n",
      "  -0.25119033  0.07094732 -0.38374821  0.46967137]\n",
      " [-0.32101918 -0.40457281  0.09051426 -0.26890204 -0.37215083  0.30018987\n",
      "   0.3511168  -0.2473102   0.07026082 -0.4845351 ]\n",
      " [-0.30449892  0.44976521  0.14540741  0.28707667 -0.53217556  0.31691872\n",
      "  -0.44585037 -0.05468936  0.12461258  0.02202853]\n",
      " [-0.32994844  0.20385676 -0.61079733 -0.16625835 -0.33846242 -0.22072636\n",
      "   0.36238441  0.27559415  0.03813401  0.27722823]]\n",
      "S:\n",
      "[5.07289344 1.4055999  1.36716059 1.11666364 0.86334804 0.78338387\n",
      " 0.37994415 0.30767276 0.09431012 0.02024472]\n",
      "Vh:\n",
      "[[-0.27262345 -0.26652074  0.10405061  0.72538756 -0.08414742 -0.09088439\n",
      "   0.31009216 -0.4265167  -0.13484131 -0.0776719 ]\n",
      " [-0.25425937  0.04520607  0.30109085 -0.46820741  0.39107312 -0.48911883\n",
      "   0.13006985 -0.41569692 -0.19541328  0.05788642]\n",
      " [-0.40429642 -0.20077966 -0.00505956 -0.08932386 -0.30829822 -0.32117608\n",
      "  -0.41886425  0.1070886   0.18633471 -0.60695128]\n",
      " [-0.3774786  -0.47437482  0.3265406   0.00890344  0.1112312   0.23117319\n",
      "  -0.34833472  0.29548801 -0.219787    0.45055568]\n",
      " [-0.20333144  0.15825926  0.08835922  0.21095454  0.71314927  0.26104752\n",
      "  -0.08242877  0.04246137  0.49118993 -0.23389841]\n",
      " [-0.28987134 -0.24400491 -0.33595186 -0.33710677 -0.20605219  0.33978128\n",
      "   0.11481969 -0.45022382  0.4504628   0.23069672]\n",
      " [-0.33962756  0.29074203  0.19674652  0.06908409 -0.24368987 -0.30729117\n",
      "   0.39812525  0.41634699  0.40458678  0.32754967]\n",
      " [-0.35166419  0.55226685 -0.41440902  0.2053375  -0.00324635 -0.08233205\n",
      "  -0.44540722 -0.16148712 -0.21471786  0.28297837]\n",
      " [-0.32337716 -0.15847562 -0.55905995 -0.1175875   0.24286336  0.03103938\n",
      "   0.43084064  0.37344471 -0.35089479 -0.18915607]\n",
      " [-0.29347315  0.40292761  0.38496799 -0.16622567 -0.25128384  0.55690275\n",
      "   0.16627485 -0.0557685  -0.2889617  -0.29690227]]\n",
      "Singular values:\n",
      "[5.07289344 1.4055999  1.36716059 1.11666364 0.86334804 0.78338387\n",
      " 0.37994415 0.30767276 0.09431012 0.02024472]\n",
      "Approximation:\n",
      "[[ 0.06038225  0.06130983  0.04786954 -0.92148867  0.19257532  0.25227454\n",
      "  -0.69659196  0.77490777  0.15040108  0.22965862]\n",
      " [ 0.12736687  0.04523095 -0.11243601 -0.84447909 -0.1398487   0.24450042\n",
      "  -0.78486753  0.88639659  0.216682    0.02253609]\n",
      " [ 0.58585981  0.4623613  -0.2520688  -0.8226427   0.27206799  0.60413215\n",
      "  -0.49171183  0.90321828  0.38458752  0.26569345]\n",
      " [ 0.21668867  0.43218681 -0.14929882 -1.42179175  0.09809086 -0.15054978\n",
      "  -0.72093313  0.68139761  0.36218905 -0.27487784]\n",
      " [ 0.16555477  0.57670266  0.07468278 -1.32974614  0.74129015 -0.18108187\n",
      "  -0.31852875  0.2503787   0.29792042 -0.02209959]\n",
      " [ 0.72129153  0.55902211 -0.20010463 -1.23471217  0.35886967  0.54160463\n",
      "  -0.47775648  0.92818957  0.23100041  0.52294242]\n",
      " [ 0.57931111  0.67210095 -0.44030103 -1.16300985 -0.09605998 -0.02133907\n",
      "  -0.49138729  0.64868332  0.50066933 -0.42332146]\n",
      " [ 0.71720079  0.47506877 -0.46773351 -0.99654233 -0.38603951  0.23311758\n",
      "  -0.49970423  0.8418563   0.26195111 -0.04167767]\n",
      " [ 0.15242004  0.17557477  0.09269639 -1.52832198  0.02392478 -0.27850827\n",
      "  -0.5538287   0.49254066 -0.174343    0.28781424]\n",
      " [ 0.85056686  0.6685415  -0.17010261 -1.33701503  0.28131023  0.16097044\n",
      "  -0.04322733  0.43809496 -0.0886243   0.63813299]]\n"
     ]
    }
   ],
   "source": [
    "if __name__ == \"__main__\":\n",
    "    # 创建一个随机矩阵\n",
    "    matrix = np.random.rand(10, 10)\n",
    "\n",
    "    # 计算矩阵的SVD分解\n",
    "    u, s, vh = svd_decomposition(matrix)\n",
    "    print(\"U:\")\n",
    "    print(u)\n",
    "    print(\"S:\")\n",
    "    print(s)\n",
    "    print(\"Vh:\")\n",
    "    print(vh)\n",
    "\n",
    "    # 计算矩阵的奇异值\n",
    "    singular_values = calculate_singular_values(matrix)\n",
    "    print(\"Singular values:\")\n",
    "    print(singular_values)\n",
    "\n",
    "    # 计算矩阵的近似\n",
    "    k = 5\n",
    "    approximation = calculate_approximation(matrix, k)\n",
    "    print(\"Approximation:\")\n",
    "    print(approximation)\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "warehouse",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
